<template>
  <div class="tencent-map-container">
    <!-- 地图容器 -->
    <div 
      :id="mapId" 
      class="tencent-map"
      :style="{ width: width, height: height }">
    </div>
    
    <!-- 加载状态 -->
    <div v-if="loading" class="map-loading">
      <i class="el-icon-loading"></i>
      <span>地图加载中...</span>
    </div>
    
    <!-- 错误状态 -->
    <div v-if="error" class="map-error">
      <i class="el-icon-warning"></i>
      <span>{{ error }}</span>
      <el-button size="mini" @click="retryLoad">重试</el-button>
    </div>
  </div>
</template>

<script>
import setting from '@/config/setting'

export default {
  name: 'TencentMap',
  props: {
    // 地图宽度
    width: {
      type: String,
      default: '100%'
    },
    // 地图高度
    height: {
      type: String,
      default: '300px'
    },
    // 地图中心点
    center: {
      type: Object,
      default: () => setting.tencentMap.defaultOptions.center
    },
    // 缩放级别
    zoom: {
      type: Number,
      default: setting.tencentMap.defaultOptions.zoom
    },
    // 标记点数据
    markers: {
      type: Array,
      default: () => []
    },
    // 是否显示控件
    showControls: {
      type: Boolean,
      default: true
    },
    // 地图类型
    mapType: {
      type: String,
      default: 'roadmap'
    },
    // 标记图标类型
    markerIconType: {
      type: String,
      default: 'store',
      validator: (value) => ['store', 'rider', 'destination'].includes(value)
    }
  },
  data() {
    return {
      mapId: `tencent-map-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
      map: null,
      loading: true,
      error: null,
      markerInstances: [], // 存储标记实例
      infoWindow: null, // 信息窗口实例
      mapReadyEmitted: false, // 标记是否已经触发过map-ready事件
      // 图标映射表
      iconMap: {
        store: '店',
        rider: '🚴',
        destination: '收'
      }
    }
  },
  mounted() {
    this.initMap()
  },
  beforeDestroy() {
    this.destroyMap()
  },
  watch: {
    center: {
      handler(newCenter) {
        if (this.map && newCenter) {
          this.map.setCenter(new TMap.LatLng(newCenter.lat, newCenter.lng))
        }
      },
      deep: true
    },
    zoom(newZoom) {
      if (this.map && newZoom) {
        this.map.setZoom(newZoom)
      }
    },
    markers: {
      handler(newMarkers) {
        this.updateMarkers(newMarkers)
      },
      deep: true
    }
  },
  methods: {
    /**
     * 初始化地图
     */
    async initMap() {
      try {
        this.loading = true
        this.error = null
        
        // 加载腾讯地图API
        await this.loadTencentMapAPI()
        
        // 创建地图实例
        this.map = new TMap.Map(this.mapId, {
          center: new TMap.LatLng(this.center.lat, this.center.lng),
          zoom: this.zoom,
          mapTypeId: this.mapType,
          // 控件配置
          control: {
            scale: this.showControls,
            zoom: this.showControls,
            rotation: this.showControls
          }
        })
        
        // 地图加载完成事件
        this.map.on('tilesloaded', () => {
          this.loading = false
          // 确保map-ready事件只触发一次
          if (!this.mapReadyEmitted) {
            this.mapReadyEmitted = true
            this.$emit('map-ready', this.map)
          }
        })
        
        // 地图点击事件
        this.map.on('click', (evt) => {
          this.$emit('map-click', {
            lat: evt.latLng.lat,
            lng: evt.latLng.lng,
            event: evt
          })
        })
        
        // 初始化标记
        this.updateMarkers(this.markers)
        
      } catch (error) {
        console.error('地图初始化失败:', error)
        this.loading = false
        this.error = '地图加载失败，请检查网络连接'
      }
    },
    
    /**
     * 加载腾讯地图API
     */
    loadTencentMapAPI() {
      return new Promise((resolve, reject) => {
        // 如果已经加载过，直接返回
        if (window.TMap) {
          resolve()
          return
        }

        // 检查是否正在加载中
        if (window.tencentMapLoading) {
          // 等待加载完成
          const checkLoaded = () => {
            if (window.TMap) {
              resolve()
            } else {
              setTimeout(checkLoaded, 100)
            }
          }
          checkLoaded()
          return
        }

        // 标记正在加载
        window.tencentMapLoading = true

        // 创建script标签加载API
        const script = document.createElement('script')
        script.type = 'text/javascript'
        script.src = `https://map.qq.com/api/gljs?v=${setting.tencentMap.version}&key=${setting.tencentMap.key}&callback=tencentMapInit`

        // 设置全局回调函数
        window.tencentMapInit = () => {
          delete window.tencentMapInit
          delete window.tencentMapLoading
          resolve()
        }

        script.onerror = () => {
          delete window.tencentMapInit
          delete window.tencentMapLoading
          reject(new Error('腾讯地图API加载失败'))
        }

        // 设置超时
        setTimeout(() => {
          if (!window.TMap) {
            delete window.tencentMapInit
            delete window.tencentMapLoading
            reject(new Error('腾讯地图API加载超时'))
          }
        }, 10000)

        document.head.appendChild(script)
      })
    },
    
    /**
     * 更新标记点
     */
    updateMarkers(markers) {
      if (!this.map || !markers) return
      
      // 清除现有标记
      this.clearMarkers()
      
      // 添加新标记
      markers.forEach(marker => {
        this.addMarker(marker)
      })
    },
    
    /**
     * 添加标记点
     */
    addMarker(markerData) {
      if (!this.map || !markerData.lat || !markerData.lng) return

      const marker = new TMap.MultiMarker({
        map: this.map,
        styles: {
          'default': new TMap.MarkerStyle({
            width: 40,
            height: 50,
            anchor: { x: 20, y: 50 },
            src: markerData.icon || this.createCustomMarkerIcon(markerData)
          }),
          'highlighted': new TMap.MarkerStyle({
            width: 50,
            height: 60,
            anchor: { x: 25, y: 60 },
            src: this.createHighlightedMarkerIcon(markerData)
          })
        },
        geometries: [{
          id: markerData.id || `marker-${Date.now()}`,
          styleId: 'highlighted', // 使用高亮样式
          position: new TMap.LatLng(markerData.lat, markerData.lng),
          properties: markerData
        }]
      })

      // 添加标记点动画效果
      this.addMarkerAnimation(marker, markerData)
      
      // 标记点击事件
      marker.on('click', (evt) => {
        const properties = evt.geometry.properties
        this.$emit('marker-click', properties)
        
        // 显示信息窗口
        if (markerData.showInfo !== false) {
          this.showInfoWindow(markerData, evt.geometry.position)
        }
      })
      
      this.markerInstances.push(marker)
      return marker
    },
    
    /**
     * 显示信息窗口
     */
    showInfoWindow(markerData, position) {
      // 关闭现有信息窗口
      if (this.infoWindow) {
        this.infoWindow.close()
      }
      
      // 创建信息窗口内容
      const content = markerData.infoContent || `
        <div class="map-info-window">
          <h4>${markerData.title || '位置信息'}</h4>
          ${markerData.address ? `<p><i class="el-icon-location-outline"></i> ${markerData.address}</p>` : ''}
          ${markerData.description ? `<p>${markerData.description}</p>` : ''}
        </div>
      `
      
      // 创建信息窗口
      this.infoWindow = new TMap.InfoWindow({
        map: this.map,
        position: position,
        content: content,
        offset: { x: 0, y: -35 }
      })
      
      this.infoWindow.open()
    },
    
    /**
     * 清除所有标记
     */
    clearMarkers() {
      this.markerInstances.forEach(marker => {
        marker.setMap(null)
      })
      this.markerInstances = []
      
      if (this.infoWindow) {
        this.infoWindow.close()
        this.infoWindow = null
      }
    },
    
    /**
     * 设置地图中心点
     */
    setCenter(lat, lng) {
      if (this.map) {
        this.map.setCenter(new TMap.LatLng(lat, lng))
      }
    },
    
    /**
     * 设置缩放级别
     */
    setZoom(zoom) {
      if (this.map) {
        this.map.setZoom(zoom)
      }
    },
    
    /**
     * 适应所有标记点
     */
    fitBounds(customPadding = null) {
      if (this.map && this.markers.length > 0) {
        try {
          const bounds = new TMap.LatLngBounds()
          this.markers.forEach(marker => {
            bounds.extend(new TMap.LatLng(marker.lat, marker.lng))
          })

          // 根据标记点数量和类型智能调整padding
          let padding = customPadding
          if (!padding) {
            if (this.markers.length === 1) {
              padding = 50  // 单个标记点，较小的padding
            } else {
              padding = 100 // 多个标记点，较大的padding以便看清相对位置
            }
          }

          this.map.fitBounds(bounds, { padding })
          console.log(`地图自适应完成，包含 ${this.markers.length} 个标记点，padding: ${padding}`)
        } catch (error) {
          console.warn('地图自适应失败:', error)
          // 如果自适应失败，使用智能缩放级别
          if (this.markers.length > 0) {
            const firstMarker = this.markers[0]
            this.setCenter(firstMarker.lat, firstMarker.lng)
            this.setZoom(this.markers.length > 1 ? 11 : 13)
          }
        }
      }
    },
    
    /**
     * 重试加载
     */
    retryLoad() {
      this.initMap()
    },
    
    /**
     * 创建自定义标记图标
     */
    createCustomMarkerIcon(markerData = {}) {
      const canvas = document.createElement('canvas')
      canvas.width = 40
      canvas.height = 50
      const ctx = canvas.getContext('2d')

      // 绘制标记背景（红色圆形）
      ctx.fillStyle = '#FF4444'
      ctx.beginPath()
      ctx.arc(20, 20, 18, 0, 2 * Math.PI)
      ctx.fill()

      // 绘制白色边框
      ctx.strokeStyle = '#FFFFFF'
      ctx.lineWidth = 3
      ctx.stroke()

      // 绘制底部三角形
      ctx.fillStyle = '#FF4444'
      ctx.beginPath()
      ctx.moveTo(20, 38)
      ctx.lineTo(12, 25)
      ctx.lineTo(28, 25)
      ctx.closePath()
      ctx.fill()

      // 根据图标类型绘制不同图标
      ctx.fillStyle = '#FFFFFF'
      ctx.font = 'bold 16px Arial'
      ctx.textAlign = 'center'
      // 优先使用 markerData.type，其次使用 markerIconType
      const iconType = markerData.type || this.markerIconType
      ctx.fillText(this.iconMap[iconType], 20, 26)

      return canvas.toDataURL()
    },

    /**
     * 创建高亮标记图标
     */
    createHighlightedMarkerIcon(markerData = {}) {
      const canvas = document.createElement('canvas')
      canvas.width = 50
      canvas.height = 60
      const ctx = canvas.getContext('2d')

      // 绘制外圈光晕效果
      const gradient = ctx.createRadialGradient(25, 25, 0, 25, 25, 25)
      gradient.addColorStop(0, 'rgba(255, 68, 68, 0.8)')
      gradient.addColorStop(0.7, 'rgba(255, 68, 68, 0.3)')
      gradient.addColorStop(1, 'rgba(255, 68, 68, 0)')
      ctx.fillStyle = gradient
      ctx.beginPath()
      ctx.arc(25, 25, 25, 0, 2 * Math.PI)
      ctx.fill()

      // 绘制主标记（更大的红色圆形）
      ctx.fillStyle = '#FF4444'
      ctx.beginPath()
      ctx.arc(25, 25, 20, 0, 2 * Math.PI)
      ctx.fill()

      // 绘制白色边框
      ctx.strokeStyle = '#FFFFFF'
      ctx.lineWidth = 4
      ctx.stroke()

      // 绘制底部三角形
      ctx.fillStyle = '#FF4444'
      ctx.beginPath()
      ctx.moveTo(25, 45)
      ctx.lineTo(15, 30)
      ctx.lineTo(35, 30)
      ctx.closePath()
      ctx.fill()

      // 根据图标类型绘制不同图标
      ctx.fillStyle = '#FFFFFF'
      ctx.font = 'bold 18px Arial'
      ctx.textAlign = 'center'
      // 优先使用 markerData.type，其次使用 markerIconType
      const iconType = markerData.type || this.markerIconType
      ctx.fillText(this.iconMap[iconType], 25, 31)

      return canvas.toDataURL()
    },

    /**
     * 添加标记点动画效果
     */
    addMarkerAnimation(marker, markerData) {
      // 添加脉冲动画效果
      setTimeout(() => {
        if (this.map) {
          // 创建脉冲圆圈
          const pulseCircle = new TMap.Circle({
            map: this.map,
            center: new TMap.LatLng(markerData.lat, markerData.lng),
            radius: 50,
            strokeColor: '#FF4444',
            strokeWeight: 2,
            fillColor: '#FF4444',
            fillOpacity: 0.1
          })

          // 动画效果
          let radius = 50
          let opacity = 0.3
          const animate = () => {
            radius += 5
            opacity -= 0.02

            if (opacity > 0) {
              pulseCircle.setRadius(radius)
              pulseCircle.setOptions({
                fillOpacity: opacity,
                strokeOpacity: opacity
              })
              requestAnimationFrame(animate)
            } else {
              pulseCircle.setMap(null)
            }
          }
          animate()
        }
      }, 500)
    },

    /**
     * 销毁地图
     */
    destroyMap() {
      if (this.map) {
        this.clearMarkers()
        this.map.destroy()
        this.map = null
      }
      // 重置标志
      this.mapReadyEmitted = false
    }
  }
}
</script>

<style scoped>
.tencent-map-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.tencent-map {
  width: 100%;
  height: 100%;
  border-radius: 4px;
  overflow: hidden;
}

.map-loading,
.map-error {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
  color: #666;
  font-size: 14px;
}

.map-loading i,
.map-error i {
  font-size: 24px;
  margin-bottom: 10px;
}

.map-error {
  color: #f56c6c;
}

.map-error .el-button {
  margin-top: 10px;
}

/* 信息窗口样式 */
:global(.map-info-window) {
  padding: 12px;
  min-width: 200px;
  max-width: 300px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

:global(.map-info-window h4) {
  margin: 0 0 10px 0;
  color: #303133;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
}

:global(.map-info-window p) {
  margin: 0 0 6px 0;
  color: #606266;
  font-size: 13px;
  line-height: 1.5;
  display: flex;
  align-items: center;
}

:global(.map-info-window i) {
  margin-right: 6px;
  color: #409EFF;
  flex-shrink: 0;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .tencent-map {
    height: 250px !important;
  }

  :global(.map-info-window) {
    min-width: 180px;
    max-width: 250px;
    padding: 10px;
  }

  :global(.map-info-window h4) {
    font-size: 14px;
  }

  :global(.map-info-window p) {
    font-size: 12px;
  }
}
</style>
